import { Injectable } from '@nestjs/common';
import { User } from './user.model';
import { LoginProvider } from '@app/constants/thirdparty'
import { InjectModel } from '@app/transformers/model.transformer'
import { MongooseModel } from '@app/interfaces/mongoose.interface'
import { OAuth } from '@app/modules/auth/auth.model';


@Injectable()
export class UserService {
  constructor(
    @InjectModel(User) private readonly userModel: MongooseModel<User>,
    @InjectModel(OAuth) private readonly oauthModel: MongooseModel<OAuth>
  ) { }

  // 创建用户
  async createUser(user: User):Promise<User> {
    return this.userModel.create(user)
  }

  // 查询用户
  async findById(id: string): Promise<User | null> {
    return this.userModel.findById(id).select('-password').lean()
  }

  // 通过手机号码查询用户
  async findByTelphone(tel: number): Promise<User | null> {
    return this.userModel.findOne({ telphone: tel }).lean()
  }

  // 通过手机号码查询用户
  async findByUsername(username: string): Promise<User | null> {
    return this.userModel.findOne({ username }).lean()
  }

  // 通过第三方查询用户
  async findByOauth(provider: LoginProvider, openid: string): Promise<User | null> {
    const oauthRecord = await this.oauthModel.findOne({
      provider,
      openid
    })
      .populate('user')
      .exec()

    return oauthRecord?.user as User || null
  }

  // 创建用户并绑定第三方凭证
  async createWithOAuth(
    provider: LoginProvider,
    openid: string,
    unionid: string,
    profile: {
      access_token: string,
      refresh_token?: string
      expires_in?: number
      nickname?: string
      avatar?: string
    }
  ): Promise<User> {
    const user = await this.userModel.create({
      nickname: profile.nickname || `User_${Math.random().toString(36).substr(2, 8)}`,
      avatar: profile.avatar
    })
    // 绑定第三方凭证
    await this.oauthModel.create({
      user: user._id,
      provider,
      unionid,
      openid,
      ...profile
    })

    return user
  }

  // 更新第三方登录凭证
  async updateOAuthToken(
    provider: LoginProvider,
    openid: string,
    tokenData: {
      access_token: string,
      refresh_token?: string
      expires_in?: number
    },
  ) {
    return this.oauthModel.updateOne(
      { provider, openid },
      { $set: { ...tokenData, updateAt: new Date() }}
    )
  }

  // 绑定已有用户
  async bindOAuthToUser(
    userId: string,
    provider: LoginProvider,
    openid: string,
    tokenData: {
      access_token: string,
      refresh_token?: string
      expires_in?: number
    }
  ) {
    await this.oauthModel.create({
      user: userId,
      provider,
      openid,
      ...tokenData
    })
  }
}
